//
// Created by Pulsar on 2020/5/18.
//

#include <rc_network/rc_httpd_rest.h>
#include <base/slog.hpp>
#include <iostream>
#include <rc_message/rc_msg_server.h>
#include <boost/thread/mutex.hpp>
#include <rc_task/queue_sources_locks.h>
#include <rc_move/rcmove.h>
namespace RC {
    namespace Network {
        namespace Httpd {
            void printCookies(const Http::Request &req) {
                auto cookies = req.cookies();
                std::cout << "Cookies: [" << std::endl;
                const std::string indent(4, ' ');
                for (const auto &c: cookies) {
                    std::cout << indent << c.name << " = " << c.value << std::endl;
                }
                std::cout << "]" << std::endl;
            }


            rcHttpdRest::rcHttpdRest(int port) {
                Port serv_port(port);
                Address addr(Ipv4::any(), serv_port);
                httpEndpoint = std::make_shared<Http::Endpoint>(addr);

            }

            void rcHttpdRest::init(size_t thr) {
                auto opts = Http::Endpoint::options()
                        .threads(static_cast<int>(thr));
                httpEndpoint->init(opts);
                setupRoutes();
            }

            void rcHttpdRest::start() {
                httpEndpoint->setHandler(router.handler());
                httpEndpoint->serve();
            }

            void rcHttpdRest::setupRoutes() {
                using namespace Rest;
                Routes::Get(router, "/", Routes::bind(&rcHttpdRest::index, this));
                Routes::Get(router, "/index", Routes::bind(&rcHttpdRest::index, this));
                Routes::Get(router, "/js/:filename", Routes::bind(&rcHttpdRest::staticfile, this));
                Routes::Get(router, "/css/:filename", Routes::bind(&rcHttpdRest::staticfile, this));
                Routes::Get(router, "/image/:filename", Routes::bind(&rcHttpdRest::staticfile, this));
                Routes::Get(router, "/move/:action", Routes::bind(&rcHttpdRest::move, this));
                Routes::Get(router, "/video", Routes::bind(&rcHttpdRest::video, this));
                Routes::Get(router, "/settings", Routes::bind(&rcHttpdRest::settings, this));
                Routes::Post(router, "/settings", Routes::bind(&rcHttpdRest::settings, this));

            }

            void rcHttpdRest::settings(const Rest::Request &request, Http::ResponseWriter response) {
                // TODO:输出系统信息
                time_t now = time(0);
                std::string local_date_time = ctime(&now);
                boost::mutex::scoped_lock lock(RC::Message::ImageMessage::image_mutex);
                response.send(Http::Code::Ok, "{state:\"Radar\":\"/dev/USB0\"}");
            }
            void rcHttpdRest::video(const Rest::Request &request, Http::ResponseWriter response) {
                time_t now = time(0);
                std::string local_date_time = ctime(&now);
                boost::mutex::scoped_lock lock(RC::Message::ImageMessage::image_mutex);
                std::string strRespon = Message::MessageServer::imageMessage.front_message();
                if (strRespon.size() == 0) {
                    response.send(Http::Code::Ok, local_date_time);
                } else {
                    response.send(Http::Code::Ok, strRespon);
                }
            }

            void rcHttpdRest::index(const Rest::Request &request, Http::ResponseWriter response) {
                Http::serveFile(response, "html/index.html");
            }

            void rcHttpdRest::move(const Rest::Request &request, Http::ResponseWriter response) {
                std::string action = request.param(":action").as<std::string>();
//                slog::info << action << slog::endl;
                WHEEL_DATA wheelData = {0, 0, 0, 1, 1, 1};
                if (action == "ac") {
                    wheelData = {3413333, 3413333, 3413333, 1, 1, 1};
                }
                if (action == "cw") {
                    wheelData = {3413333, 3413333, 3413333, 0, 0, 0};
                }
                if (action == "front") {
                    wheelData = {3413333, 3413333, 0, 0, 1, 1};
                }
                if (action == "back") {
                    wheelData = {3413333, 3413333, 0, 1, 0, 1};
                }
                boost::mutex::scoped_lock lock(RC::Message::MoveMessage::move_mutex);

                RC::Message::MessageServer::moveMessage.push_message(wheelData);
                response.send(Http::Code::Ok, action);
            }

            void rcHttpdRest::staticfile(const Rest::Request &request, Http::ResponseWriter response) {
                std::string res_path = "html/";
                std::string filename = request.param(":filename").as<std::string>();
                std::string file_ext_name = filename.substr(filename.find_last_of('.') + 1);

                if (file_ext_name == "js") {
                    response.headers().add<Http::Header::ContentType>(MIME(Application, Javascript));
                    res_path = res_path + "js/" + filename;
                }
                if (file_ext_name == "css") {
                    response.headers().add<Http::Header::ContentType>(MIME(Text, Css));
                    res_path = res_path + "css/" + filename;
                }
                if (file_ext_name == "png" || file_ext_name == "gif" || file_ext_name == "jpeg") {
                    response.headers().add<Http::Header::ContentType>(MIME(Image, Jpeg));
                    res_path = res_path + "image/" + filename;
                }
                slog::wget << res_path << slog::endl;
                Http::serveFile(response, res_path);
            }

            void rcHttpdRest::doAuth(const Rest::Request &request, Http::ResponseWriter response) {
                response.headers().add<Http::Header::ContentType>(MIME(Text, EventStream));
                printCookies(request);
                response.cookies().add(Http::Cookie("lang", "zh-cn"));
                response.cookies().add(Http::Cookie("application", "RoboCar"));
                response.send(Http::Code::Ok);
            }
        }
    }
}